﻿/*
 * @author: wizardc
 */

using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using Object = UnityEngine.Object;
using UnityDebug = UnityEngine.Debug;

namespace Dou.Utils
{
    /// <summary>
    /// 日志等级
    /// </summary>
    [Flags]
    public enum LogLevel
    {
        None = 0,
        Error = 1,
        Warning = 1 << 1,
        Debug = 1 << 2,
        Info = 1 << 3,
        All = Error | Warning | Debug | Info
    }

    public enum LogColor : uint
    {
        Error = 0xE53D3D,
        Warning = 0xFFFF00,
        Debug = 0x5FA1E3,
    }

    /// <summary>
    /// 日志
    /// </summary>
    public static class Log
    {
        /// <summary>
        /// 日志等级
        /// </summary>
        public static LogLevel level = LogLevel.All;

        /// <summary>
        /// 是否显示时间
        /// </summary>
        public static bool showTimestamp = true;

        /// <summary>
        /// 是否显示标签
        /// </summary>
        public static bool showTag = false;

        private static Dictionary<string, long> _elapsedTimeMap = new Dictionary<string, long>();

        private static string Format(LogLevel level, string message)
        {
            StringBuilder stringBuilder = new StringBuilder();
            if (showTimestamp)
            {
                stringBuilder.Append(DateTime.Now.ToString("[HH:mm:ss:fff] "));
            }
            if (showTag)
            {
                switch (level)
                {
                    case LogLevel.Info:
                        stringBuilder.Append("[Info] ");
                        break;
                    case LogLevel.Debug:
                        stringBuilder.Append("[Debug] ");
                        break;
                    case LogLevel.Warning:
                        stringBuilder.Append("[Warning] ");
                        break;
                    case LogLevel.Error:
                        stringBuilder.Append("[Error] ");
                        break;
                }
            }
            stringBuilder.Append(message);
            return stringBuilder.ToString();
        }

        private static string FormatColor(LogLevel level, LogColor color, string message)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("<color=#");
            string colorStr = ColorUtility.ToHtmlStringRGB(ColorUtil.ParseRGB((uint) color));
            stringBuilder.Append(colorStr);
            stringBuilder.Append(">");
            string format = Format(level, message);
            format = FilesUtil.UnifyEnter(format);
            int index = format.IndexOf(FilesUtil.LINE_SEPARATOR, StringComparison.Ordinal);
            if (index == -1)
            {
                format += "</color>";
            }
            else
            {
                format = format.Insert(index, "</color>");
            }
            stringBuilder.Append(format);
            return stringBuilder.ToString();
        }

        /// <summary>
        /// 普通信息
        /// </summary>
        public static void Info(string message, Object context = null)
        {
            if (BitUtil.GetBit((uint) level, 3))
            {
                UnityDebug.Log(Format(LogLevel.Info, message), context);
            }
        }

        /// <summary>
        /// 调试信息
        /// </summary>
        public static void Debug(string message, Object context = null)
        {
            if (BitUtil.GetBit((uint) level, 2))
            {
                UnityDebug.Log(FormatColor(LogLevel.Debug, LogColor.Debug, message), context);
            }
        }

        /// <summary>
        /// 警告信息
        /// </summary>
        public static void Warning(string message, Object context = null)
        {
            if (BitUtil.GetBit((uint) level, 1))
            {
                UnityDebug.LogWarning(FormatColor(LogLevel.Warning, LogColor.Warning, message), context);
            }
        }

        /// <summary>
        /// 错误信息
        /// </summary>
        public static void Error(string message, Object context = null)
        {
            if (BitUtil.GetBit((uint) level, 0))
            {
                UnityDebug.LogError(FormatColor(LogLevel.Error, LogColor.Error, message), context);
            }
        }

        /// <summary>
        /// 标记当前时间
        /// </summary>
        public static void MarkElapsedTime(string name)
        {
            _elapsedTimeMap[name] = DateTime.Now.Ticks / 10000;
        }

        /// <summary>
        /// 获取和上次标记的间隔，毫秒
        /// </summary>
        /// <param name="remove">是否移除时间标记</param>
        /// <param name="keep">是否将当前时间进行保留, 不保留仍然标记上一次的时间</param>
        public static int GetElapsedTime(string name, bool remove = false, bool keep = true)
        {
            if (!_elapsedTimeMap.ContainsKey(name))
            {
                return -1;
            }
            long last = _elapsedTimeMap[name];
            long now = DateTime.Now.Ticks / 10000;
            long elapsed = now - last;
            if (remove)
            {
                _elapsedTimeMap.Remove(name);
            }
            else if (keep)
            {
                _elapsedTimeMap[name] = now;
            }
            return (int) elapsed;
        }
    }
}
